package com.ryan.ohos.extension.util;

import ohos.agp.utils.Color;
import ohos.utils.PlainArray;

import java.lang.ref.WeakReference;

public class ColorStateList {

    public int[][] mStateSpecs;
    public int[] mColors;
    public int mDefaultColor = Color.RED.getValue();

    private static final PlainArray<WeakReference<ColorStateList>> sCache = new PlainArray<>();

    private ColorStateList() {
    }

    /**
     * Creates a ColorStateList that returns the specified mapping from
     * states to colors.
     */
    public ColorStateList(int[][] states, int[] colors) {

        mStateSpecs = states.clone();
        mColors = colors.clone();
    }

    public int getDefaultColor() {
        return mDefaultColor;
    }

    public static ColorStateList valueOf(int color) {
        synchronized (sCache) {
            final int index = sCache.indexOfKey(color);
            if (index >= 0) {
                final ColorStateList cached = sCache.valueAt(index).get();
                if (cached != null) {
                    return cached;
                }

                // Prune missing entry.
                sCache.removeAt(index);
            }

            // Prune the cache before adding new items.
            final int N = sCache.size();
            for (int i = N - 1; i >= 0; i--) {
                if (sCache.valueAt(i).get() == null) {
                    sCache.removeAt(i);
                }
            }

            final ColorStateList csl = new ColorStateList(new int[0][0], new int[] { color });
            sCache.put(color, new WeakReference<>(csl));
            return csl;
        }
    }

    /**
     * Returns whether the specified state is referenced in any of the state
     * specs contained within this ColorStateList.
     * <p>
     * Any reference, either positive or negative {ex. ~R.attr.state_enabled},
     * will cause this method to return {@code true}. Wildcards are not counted
     * as references.
     *
     * @param state the state to search for
     * @return {@code true} if the state if referenced, {@code false} otherwise
     * @hide Use only as directed. For internal use only.
     */
    public boolean hasState(int state) {
        final int[][] stateSpecs = mStateSpecs;
        final int specCount = stateSpecs.length;
        for (int specIndex = 0; specIndex < specCount; specIndex++) {
            final int[] states = stateSpecs[specIndex];
            final int stateCount = states.length;
            for (int stateIndex = 0; stateIndex < stateCount; stateIndex++) {
                if (states[stateIndex] == state || states[stateIndex] == ~state) {
                    return true;
                }
            }
        }
        return false;
    }

}
